package com.audaque.springboot.foshanupload.core.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author zgb
 * @desc ...
 * @date 2023-03-01 20:00:22
 */
public class CalendarUtils {

    /**
     * 获取当前年
     *
     * @return
     */
    public static int getNowYear() {
        Calendar d = Calendar.getInstance();
        return d.get(Calendar.YEAR);
    }

    /**
     * 获取当前月份
     *
     * @return
     */
    public static int getNowMonth() {
        Calendar d = Calendar.getInstance();
        return d.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当月天数
     *
     * @return
     */
    public static int getNowMonthDay() {
        Calendar d = Calendar.getInstance();
        return d.getActualMaximum(Calendar.DATE);
    }


    /**
     * 获取提前多少个月
     *
     * @param monty
     * @return
     */
    public static Date getFirstMonth(int monty) {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -monty);
        return c.getTime();
    }


    /**
     * 获取两日期差，返回年月日差值
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<Integer> getDiffDates(Date startDate, Date endDate) {
        String dates = "";
        List<Integer> diffList = new ArrayList<Integer>();
        try {
            Calendar calS = Calendar.getInstance();
            // 开始时间
            calS.setTime(startDate);
            int startY = calS.get(Calendar.YEAR);
            int startM = calS.get(Calendar.MONTH);
            int startD = calS.get(Calendar.DATE);
            int startDayOfMonth = calS.getActualMaximum(Calendar.DAY_OF_MONTH);
            // 结束时间
            calS.setTime(endDate);
            int endY = calS.get(Calendar.YEAR);
            int endM = calS.get(Calendar.MONTH);
            // 处理起止日期为同一天，默认服务为一天 示例：2016-01-01 至 2016-01-01
            int endD = calS.get(Calendar.DATE) + 1;
            int endDayOfMonth = calS.getActualMaximum(Calendar.DAY_OF_MONTH);
            int lday = endD - startD;
            // 每月按照30天计算
            if (endD < startD) {
                endM = endM - 1;
                lday = 30 - startD + endD;
            }
            /*
             * 按照正常日期计算 if (lday<0) { endM = endM -1; lday = startDayOfMonth+
             * lday; }
             */
            // 处理服务天数问题，示例：2016-01-01 到 2017-12-31 实际上是1年
            if (lday == endDayOfMonth) {
                endM = endM + 1;
                lday = 0;
            }
            int mos = (endY - startY) * 12 + (endM - startM);
            int lyear = mos / 12;
            int lmonth = mos % 12;
            diffList.add(lyear);
            diffList.add(lmonth);
            diffList.add(lday);
            dates = lyear + "年" + lmonth + "个月" + lday + "天";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return diffList;
    }


    /**
     * 获得两个日期之间的所有月份
     *
     * @param minDate
     * @param maxDate
     * @return
     * @throws Exception
     */
    public static List<String> getMonthBetween(String minDate, String maxDate) throws Exception {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月
        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.setTime(sdf.parse(minDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);
        max.setTime(sdf.parse(maxDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);
        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }


    //等到当期时间的周系数。星期日：1，星期一：2，星期二：3，星期三：4，星期四：5，星期五：6，星期六：7
    public static Integer dayForWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_WEEK);
    }


    /**
     * 获取当前日期是星期几<br>
     *
     * @param date
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(Date date) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }


    /**
     * 获取固定日期
     *
     * @param begin
     * @param end
     * @return
     */
    public static List<Date> getData(Date begin, Date end, int day) {
        Calendar l_begin = Calendar.getInstance();
        l_begin.clear();
        l_begin.setTime(begin);

        Calendar l_end = Calendar.getInstance();
        l_end.clear();
        l_end.setTime(end);
        List<Date> list = new ArrayList<Date>();
        boolean ifOk = true;
        if (day == l_begin.get(Calendar.DATE)) {
            list.add(new Date(l_begin.getTimeInMillis()));
        }
        do {
            l_begin.add(Calendar.DATE, 1);
            if (day == l_begin.get(Calendar.DATE) && l_begin.compareTo(l_end) == -1) {
                list.add(new Date(l_begin.getTimeInMillis()));
            }
            if (l_begin.compareTo(l_end) == 1) {
                ifOk = false;
            }
        } while (ifOk);
        return list;
    }

    /**
     * 清空时分秒
     *
     * @param date
     * @return
     */
    public static void clearHHMMSS(Date date) {
        if (date == null) {
            return;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 将时分秒,毫秒域清零
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        date.setTime(cal.getTime().getTime());
    }

    /**
     * 格式化日期 yyyy-MM 月份-1
     *
     * @param date
     * @return
     */
    public static Date getPreYearMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        return calendar.getTime();
    }

    public static int compareYearMonth(Date d1, Date d2) {

        Calendar c1 = Calendar.getInstance();
        c1.setTime(d1);
        int y1 = c1.get(Calendar.YEAR);
        int m1 = c1.get(Calendar.MONTH);

        Calendar c2 = Calendar.getInstance();
        c2.setTime(d2);
        int y2 = c2.get(Calendar.YEAR);
        int m2 = c2.get(Calendar.MONTH);
        if (y1 == y2) {
            return m1 - m2;
        }
        return y1 - y2;
    }

    public static int compareYearMonthDay(Date d1, Date d2) {
        int compareYearMonth = compareYearMonth(d1, d2);
        if (compareYearMonth == 0) {
            Calendar c1 = Calendar.getInstance();
            c1.setTime(d1);
            int day1 = c1.get(Calendar.DAY_OF_MONTH);

            Calendar c2 = Calendar.getInstance();
            c2.setTime(d2);
            int day2 = c2.get(Calendar.DAY_OF_MONTH);
            return day1 - day2;
        }
        return compareYearMonth;
    }

    /**
     * 获取指定日期所在月总天数
     *
     * @param sourceDate
     * @return
     */
    public static int getMonthDayCount(Date sourceDate) {
        Calendar d = Calendar.getInstance();
        d.setTime(sourceDate);
        return d.getActualMaximum(Calendar.DATE);
    }


    /**
     * 获取某一时间段特定星期几的日期
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     * @param weekDays  星期几
     * @param dateTime  具体时间
     *                  getDates("2013-04-01", "2014-04-14","星期一|星期二|星期日");
     * @return 返回时间数组
     */
    public static List<Date> getDates(Date beginTime, Date endTime, String weekDays, Date dateTime) throws Exception {
        String dateFrom = null;
        String dateEnd = null;
        long time = 1L;
        long perDayMilSec = 24 * 60 * 60 * 1000;
        List<Date> dateList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat hms = new SimpleDateFormat("hh:mm:ss");
        //需要查询的星期系数
        String strWeekNumber = OnlyDateUtils.weekForNum(weekDays);
        String houreTime = null;
        if (dateTime != null) {
            houreTime = hms.format(dateTime);
        }
        try {
            dateFrom = sdf.format(beginTime.getTime() - perDayMilSec);
            dateEnd = sdf.format(endTime);
            while (true) {
                time = sdf.parse(dateFrom).getTime();
                time = time + perDayMilSec;
                Date date = new Date(time);
                dateFrom = sdf.format(date);
                if (dateFrom.compareTo(dateEnd) <= 0) {
                    //查询的某一时间的星期系数
                    Integer weekDay = dayForWeek(date);
                    //判断当期日期的星期系数是否是需要查询的
                    if (strWeekNumber.indexOf(weekDay.toString()) != -1) {
                        Date timeDate = sdf.parse(dateFrom + " " + houreTime);
                        dateList.add(timeDate);
                    }
                } else {
                    break;
                }
            }
        } catch (ParseException e1) {
            e1.printStackTrace();
        }
        return dateList;
    }

    /**
     * 获取指定年月的最后一天
     * @param year
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        //设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        return sdf.format(cal.getTime());
    }



    /**
     * 获取指定年月的第一天
     * @param year
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month-1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        //设置日历中月份的最小天数
        cal.set(Calendar.DAY_OF_MONTH,firstDay);
        //格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        return sdf.format(cal.getTime());
    }
    public static String getMinuteTime(Integer i) {
        SimpleDateFormat format = new SimpleDateFormat(DateFormatUtil.DATE_TIME_FORMAT);
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, i);
        String time = format.format(cal.getTime());
        return time;
    }

    public static String getMinuteTime(String date, Integer i) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(DateFormatUtil.DATE_TIME_FORMAT);
        Calendar cal = Calendar.getInstance();
        cal.setTime(format.parse(date));
        cal.add(Calendar.MINUTE, i);
        String time = format.format(cal.getTime());
        return time;
    }

    public static String getDayTime(Integer i) {
        SimpleDateFormat format = new SimpleDateFormat(DateFormatUtil.DATE_TIME_FORMAT);
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, i);
        String time = format.format(cal.getTime());
        return time;
    }


    /**
     * 获取拼多多结算时间
     *
     * @return
     * @throws ParseException
     */
    public static Date getPddSettleDate(Date orderTime) throws ParseException {

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date = df.parse("2019-11-16");
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        long timestamp = cal.getTimeInMillis();


        return null;
    }


    /**
     * 获取淘宝结算时间
     *
     * @return
     */
    public static Date getTaobaoSettleDate(Date orderTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, 1);
        String now = sdf.format(cal.getTime()) + "-25";// 当前时间
        try {
            return sdf.parse(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }




    /**
     * 查询今天的前/后几天的整日日期
     * <p/>
     * 比如2015-12-18日的前一天--2015-12-17
     * <p/>
     * 比如2015-12-18日的后一天--2015-12-19
     *
     * @param day
     * @return
     */
    public static String getDayBeforeOrAfter(Integer day) {
        // 今天整天日期
        Date currDt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat(DateFormatUtil.DATE_PATTERN_YYYY_MM_DD);
        String currDtStr = sdf.format(currDt.getTime());
        Date currDay = null;
        try {
            currDay = sdf.parse(currDtStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date(currDay.getTime()));
        calendar.add(Calendar.DATE, day);
        Date target = calendar.getTime();
        return sdf.format(target);
    }

    /**
     * 查询某天的前/后几天的整日日期
     * <p/>
     * 比如2015-12-18日的前一天--2015-12-17
     * <p/>
     * 比如2015-12-18日的后一天--2015-12-19
     *
     * @param day
     * @return
     */
    public static String getDayBeforeOrAfter(Date sourceDt, Integer day) {
        // 今天整天日期
        if (sourceDt == null) {
            sourceDt = new Date();
        }
        SimpleDateFormat sdf = new SimpleDateFormat(DateFormatUtil.DATE_TIME_FORMAT);
        String sourceDtStr = sdf.format(sourceDt.getTime());
        Date sourceDay = null;
        try {
            sourceDay = sdf.parse(sourceDtStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date(sourceDay.getTime()));
        calendar.add(Calendar.DATE, day);
        Date target = calendar.getTime();
        return sdf.format(target);
    }









}
